package cn.kgc.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.kgc.entity.Depts;
import cn.kgc.entity.Users;
import cn.kgc.form.DeptsAddForm;
import cn.kgc.form.DeptsUpdateForm;
import cn.kgc.service.DeptsService;
import cn.kgc.service.UsersService;
import cn.kgc.util.ResultConstant;
import cn.kgc.util.exception.HttpException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/depts")
@Api
@Validated
@Slf4j
@CrossOrigin
@SuppressWarnings("all")
public class DeptsController {
    @Resource
    private DeptsService deptsService;
    @Resource
    private UsersService usersService;

    @PreAuthorize("hasAuthority('depts:list')")
    @GetMapping("/list")
    @ApiOperation(value = "查询所有数据")
    @Cacheable(value = "depts", key = "#root.methodName")
    @CrossOrigin
    public List<Depts> selectAll() {
        return deptsService.list();
    }

    @PostMapping("/list2")
    @ApiOperation(value = "根据条件查询部门的数据")
    public List<Depts> select(@RequestBody Map<String, String> params) {
        String deptName = MapUtil.getStr(params, "deptName");
        LambdaQueryWrapper<Depts> wrapper = new LambdaQueryWrapper<>();
        wrapper.likeRight(StrUtil.isNotBlank(deptName), Depts::getDeptName, deptName);
        return deptsService.list(wrapper);
    }

    @GetMapping("detail/{id}")
    @ApiOperation(value = "根据id查询部门的数据")
    @Cacheable(value = "depts", key = "#root.methodName+#id")
    public Depts selectById(@PathVariable("id") Long id) {
        return deptsService.getById(id);
    }

    @PostMapping("/update")
    @ApiOperation(value = "修改部门的数据")
    @Caching(
            evict = {
                    @CacheEvict(value = "depts", key = "'selectAll'"),
                    @CacheEvict(value = "depts", key = "'detail'+#form.getId()"),
            }
    )
    public boolean update(@RequestBody DeptsUpdateForm form) {
        Users users = null;
        //todo: 验证部门负责人是否正确
        if (form.getUserId() != 0) {
            //如果传入 验证部门负责人是否正确
            users = checkUser(form.getUserId());
        }
        Depts depts = deptsService.getById(form.getId());
        BeanUtil.copyProperties(form, depts);
        if (users != null) {
            //传入部门的负责人并且负责人存在 修改负责人的名字和邮箱
            depts.setUserName(users.getUserName());
            depts.setUserEmail(users.getUserEmail());
        } else {
            //如果没有传入部门负责人将原来的部门负责人
            depts.setUserName("");
            depts.setUserEmail("");
        }
        return deptsService.updateById(depts);
    }

    @PostMapping("/save")
    @ApiOperation(value = "添加部门")
    @CacheEvict(value = "depts", key = "'selectAll'")
    public boolean save(@RequestBody DeptsAddForm form) {
        //1 部门名称是否重复
        checkDeptName(form.getDeptName());
        //2 验证部门负责人是否正确
        Users users = null;
        if (form.getUserId() != 0) {
            users = checkUser(form.getUserId());
        }
        //3 新增部门
        Depts depts = new Depts();
        BeanUtil.copyProperties(form, depts);
        if (users != null) {
            depts.setUserName(users.getUserName());
            depts.setUserEmail(users.getUserEmail());
        }
        return deptsService.save(depts);
    }

    private void checkDeptName(String deptName) {
        LambdaQueryWrapper<Depts> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Depts::getDeptName, deptName);
        if (deptsService.count(wrapper) > 0) {
            throw new HttpException(ResultConstant.DEPT_NAME_EXIST);
        }
    }


    private Users checkUser(Integer userId) {
        Users users = usersService.getById(userId);
        if (users == null) {
            throw new HttpException(ResultConstant.DEPT_USER_NOT_EXIST);
        }
        return users;
    }
}


